/*
 * @Description: 添加用户面板
 * @Author: Rfan
 * @Date: 2022-04-19 18:12:16
 * @LastEditTime: 2022-05-25 08:59:02
 */

import { Key, useEffect, useState } from 'react';
import { Transfer, Tree } from 'antd';
import classNames from 'classnames/bind';
import { fetchDepartmentListByUnitId } from '@/api/department';
import { useAddUserDialogContext } from '../contexts/AddUserDialogContext';
import { useRoleContext } from '../../../../contexts/RoleContext';
import { fetchAllUserList } from '@/api/user';
import { delItemByIdArray } from '@/utils/list';

import styles from '../styles/panes.module.scss';
import { arrToTree } from '@/utils';

const cx = classNames.bind(styles);

const GroupPane = () => {
  const { selectUsers, setSelectUsers } = useAddUserDialogContext();
  const { userList: userTable } = useRoleContext();
  // 部门列表
  const [departmentList, setDepartmentList] = useState([]);
  // 缓存打开过的部门的用户列表
  const [allUserList, setAllUserList] = useState<any>({});
  // 已选择用户（包含完整信息）列表
  const [selectUserObj, setSelectUserObj] = useState([]);
  // 用户列表，用于展示
  const [userList, setUserList] = useState([]);
  // 选中的部门
  const [selectDepart, setSelectDepart] = useState(null);
  // 选中的用户
  const [selectedKeys, setSelectedKeys] = useState([]);

  useEffect(() => {
    fetchDepartmentListByUnitId().then((res) => {
      const data = arrToTree(res.data);
      setDepartmentList(data);
      setSelectDepart(data[0]);
    });
  }, []);

  useEffect(() => {
    if (selectDepart?.id) {
      const otherUserList = selectUserObj.filter((user) => user.departmentId !== selectDepart.id);
      if (allUserList[selectDepart.deptCode]) {
        setUserList(allUserList[selectDepart.deptCode].concat(otherUserList));
      } else {
        fetchAllUserList({ departmentId: selectDepart.id }).then((res) => {
          const { data } = res;
          const ids = userTable.map((item: any) => item.user?.id);
          const filteredList = delItemByIdArray(ids, data);
          setUserList(filteredList.concat(otherUserList));
          setAllUserList((state: any) => ({
            ...state,
            [selectDepart.deptCode]: filteredList
          }));
        });
      }
    }
  }, [selectDepart]);

  const getUserInfoArr: (keyArr: Key[]) => any[] = (keyArr: Key[]): any[] => {
    return keyArr.map((key: Key) => {
      let info: any = {};
      for (let i = 0; i < userList.length; i++) {
        const ele = userList[i];
        if (ele.id === key) {
          info = ele;
          break;
        }
      }
      return info;
    });
  };

  const onChange = (nextTargetKeys: string[], direction: any, moveKeys: any) => {
    if (direction === 'left') {
      // 删除用户时，如果用户不在当前部门，从userList中删除
      setUserList((state) =>
        state.filter(
          (user) => !(moveKeys.indexOf(user.id) > -1 && user.departmentId !== selectDepart.id)
        )
      );
    }
    // 加入到选中的key数组中
    setSelectUsers(nextTargetKeys);
    setSelectUserObj(getUserInfoArr(nextTargetKeys));
  };

  const onSelectChange = (sourceSelectedKeys: any, targetSelectedKeys: any) => {
    setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
  };

  /**
   * @description: 设置选中的部门
   * @param {Key[]} selectedKeys 选中的ID
   * @param {any} info 选中的ITEM
   */
  const chooseDepartment = (selectedKeys: Key[], info: any): void => {
    if (selectedKeys.length > 0) {
      setSelectDepart(info.node);
    }
  };

  return (
    <div className={cx('user-pane')}>
      <Tree
        className={cx('department-list')}
        onSelect={chooseDepartment}
        treeData={departmentList}
        fieldNames={{
          title: 'deptName',
          key: 'id'
        }}
        selectedKeys={[selectDepart?.id]}
      />
      <Transfer
        className={cx('user-list')}
        dataSource={userList}
        rowKey={(item) => item.id}
        titles={['待选人员', '已选人员']}
        targetKeys={selectUsers}
        selectedKeys={selectedKeys}
        onChange={onChange}
        onSelectChange={onSelectChange}
        render={(item) => `${item.realname}（${item.id}）`}
      />
    </div>
  );
};

export default GroupPane;
